package com.leyou.auth.interceptors;

import com.leyou.auth.dto.Payload;
import com.leyou.auth.dto.UserDetail;
import com.leyou.auth.utils.JwtUtils;
import com.leyou.auth.utils.UserContext;
import com.leyou.common.constants.JwtConstants;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.CookieUtils;
import io.jsonwebtoken.JwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 实现springboot提供的HandlerInterceptor只需要三步:
 * 1, 实现HandlerInterceptor接口, 编写自己的拦截器
 * 2, 编写一个类继承WebMvcConfigurerAdapter, 并重写addInterceptors方法
 * 3, 实例化我们自定义的拦截器，然后将对像手动添加到拦截器链中（在addInterceptors方法中添加）
 *
 * HandlerInterceptor 的功能跟过滤器类似，
 * 但是提供更精细的的控制能力：
 * 在request被响应之前、request被响应之后、
 * 视图渲染之前以及request全部结束之后
 */

@Slf4j
public class LoginIntereceptor implements HandlerInterceptor {

    private JwtUtils jwtUtils;

    public LoginIntereceptor(JwtUtils jwtUtils){
        this.jwtUtils = jwtUtils;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        try {
            String jwt = CookieUtils.getCookieValue(request, JwtConstants.COOKIE_NAME);
            Payload payload = jwtUtils.parseJwt(jwt);
            UserDetail userDetail = payload.getUserDetail();
            UserContext.setUser(userDetail);
            log.info("用户{}正在访问", userDetail.getUsername());
            //只有返回true才会继续向下执行，返回false取消当前请求
            return true;
        } catch (JwtException e) {
            throw new LyException(401, "jwt无效", e);
        }catch (IllegalArgumentException e){
            throw new LyException(401, "用户未登录", e);
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //业务结束, 数据已经带给前端了, 就可以把用户从线程中删除了
        UserContext.removeUser();
    }
}
